
#include "main.h" // 标准C库头文件
#include "basic_api.h" 		// 
#include "Mode.h"
#include "Mode_UTest.h"
#include "PtclAPI.h"

#include "win32app_api.h" 	// // #include "Win32UartApp.h" 

#include <windows.h>

#define LLOG
#define LLOG_ERR
#define LLOG_MARK
#define LLOG_TICK
#define LLOG_ASSERT
#include "llog.h"

//========== 系统环境变量
tvPPMgm* g_pvPPMgm;



//==========
#define CFG_WIN32_API	// mstick 函数实现
#ifdef 	CFG_WIN32_API 

#include <windows.h>
/***  note
	https://docs.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timegettime
	timeapi.h (include Windows.h)
	DWORD timeGetTime(); // 返回 ms的系统时间

	note: 编译时需要加入相应的链接库 DLL_LIB += -lwinmm
*/
static DWORD g_StartTick;
static uint32_t GetSysTick(void){
	
	static uint8_t g_InitFlag=0;
	DWORD Tmp;
	if(g_InitFlag == 0){
		g_InitFlag = 1;
		g_StartTick = timeGetTime();
	}
	
	Tmp=timeGetTime();
	if (Tmp > g_StartTick) {
		Tmp	-=	g_StartTick;
	} else {
		Tmp	=	g_StartTick-Tmp;
	}
	return Tmp;
}

#endif


//==========
static int PTask_Period_OneSec(void){

	static tMs MTick;
	static uint16_t State = 0;
	uint8_t YIELD_Flag=0;
	int ret = RET_OK;
	
	switch(State){
		case 0:{ // TODO: init 
			LLOG_TICK();
			State++;
		}break;
		case 1:{
			
			MTick =GetNowTick();
			SW_DLYMS(1,MTick,1000);
			LLOG_TICK();
			
			MTick =GetNowTick();
			SW_DLYMS(1,MTick,1000);
			LLOG_TICK();
			
			State++;
		}break;
		case 2:{
			LLOG_TICK();
			SW_YIELD(2); // 
			LLOG_TICK();
			exit(0);
		}break;
		default:{
			
		}
	}
	
	End:
	// TODO: 
	
	return ret;
}


//==========
// #define CFG_WIN_CMDLINE_PROC	// 
#ifdef 	CFG_WIN_CMDLINE_PROC

#ifdef CFG_TC_MINGW
 #include <getopt.h>		// https://www.cnblogs.com/oloroso/p/4856104.html
#endif

/* struct SysCfgPara{// define default Para 
	unsigned char DefBinFile[]="Demo.bin";
	unsigned char g_arg_ComNum = 0x03;// 0xFF;
	unsigned long g_arg_Baudrate = 115200 ;
	unsigned char g_arg_HexShowFlag = 0 ;
	char* g_arg_pFileName = &DefBinFile[0] ;
	unsigned char g_arg_YMFileSzMode = 0 ; // !=0 :Dec	
}; */

unsigned char DefBinFile[]="Demo.bin";
unsigned char g_arg_ComNum = 0xFF;// 0x03;// 0xFF;
unsigned long g_arg_Baudrate = 115200 ;
unsigned char g_arg_HexShowFlag = 0 ;
char* g_arg_pFileName = &DefBinFile[0] ;
unsigned char g_arg_YMFileSzMode = 0 ; // !=0 :Dec

static tSTimer* g_Timer_UartRx;
static tSTimer* g_Timer_UartTxTest;

static int UTTask_W32Uart_TxSend(void* pPara){ // for test 
	uint8_t TestStr[]="UartDrv Test!\n";
	int ret=RET_ERR;
	Win32_Comm_SendPkg(sizeof(TestStr)-1,&TestStr[0]);
	// LLOG_MARK();
	return ret;
}

void Input_CmdPara(int Argcmd,char * const *pArgv){

	char ch;
	uint8_t ActiveNum;
	uint8_t RedoCnt;
	ActiveNum = SerialPortList_UpdataAndShow();		// 更新串口list	
	// 
	#ifdef CFG_TC_MINGW
	// while ((ch = getopt_long(argc, argv, "", longopts, NULL)) != -1) 	
	while (( ch = getopt(Argcmd, pArgv, "p:b:f:hHD") ) != -1) 
	{
		switch (ch) {
			case 'p':{	g_arg_ComNum = atoi(optarg);	}break;
			case 'b':{	g_arg_Baudrate = atoi(optarg); 	}break;
			case 'f':{	g_arg_pFileName = optarg;		}break;
			case 'h':{	g_arg_HexShowFlag = 1; 			}break;
			case 'H':{	g_arg_HexShowFlag = 2; 			}break;
			case 'D':{	g_arg_YMFileSzMode = 1;			}break;
			case 0	:{	}break;
			default:{
			  // usage();// sscanf(optarg, "%f", &fontSize);
			  exit(1);				
			}
		}
	}
	#endif
	RedoCnt = 3;
	ReInput:
	// 选择第一有效端口 or 手动输入
	if((g_arg_ComNum == 0xFF) && (ActiveNum > 0)){ // 需要手动输入端口
		char ComNumStr[10] = {0};
		LLOG("Input ComNum(1)>> ");
		fgets(ComNumStr,sizeof(ComNumStr),stdin);//注意： 结尾多了一个0x0A!!		
		g_arg_ComNum = atoi(ComNumStr);
		// LLOG("#I ComNum = [%d]\n",g_arg_ComNum);
	}		
	
	// argc -= optind;
	// argv += optind;    
	if(RET_ERR == Check_ComNum_IsActive(g_arg_ComNum) ){
		g_arg_ComNum = 0xFF;
		LLOG("#E ComNum ERR \n");
		
		if(RedoCnt > 0){
			RedoCnt--;
			goto ReInput;
		}
		
	}
	
	LLOG("#I Input Para: ComNum=[%d], Baud=[%d] HexFlag[%d] File[%s]\n",
	g_arg_ComNum,g_arg_Baudrate,g_arg_HexShowFlag,g_arg_pFileName);
	if(g_arg_ComNum == 0xFF){ 
		LLOG_ERR();
		return ;
	}
	
	//
	#ifdef  CFG_WIN32_UART_APP
	if(RET_OK == Win32_Uart_App_Init(g_arg_ComNum,g_arg_Baudrate,g_arg_HexShowFlag)){
		tSTimer* ptmp;
		
		ptmp = STimer_CreateAndAdd(0, STIMER_TYP_PERIOD, 40);
		STimer_BindCBF(ptmp,AppTask_W32Uart_Rx);
		STimer_OnOff(ptmp,1);
		// STimer_Show(ptmp);
		g_Timer_UartRx = ptmp;

		#if 1 // for test echo;
		ptmp = STimer_CreateAndAdd(0, STIMER_TYP_PERIOD, 1000);
		STimer_BindCBF(ptmp,UTTask_W32Uart_TxSend);
		STimer_OnOff(ptmp,1);
		// STimer_Show(ptmp);
		g_Timer_UartTxTest = ptmp;
		#endif
		LLOG_MARK();
	}
	
	
	#endif
}

//
#endif

//==========
#ifdef CFG_APP_SORT_TIMER
static uint8_t g_Flag_SysRunTimeOut = 0;
static int CoTask_SysRunTimeOut(void* pPara){
	
	static int Cnt = 3; 
	
	Cnt--;
	if(Cnt == 0){
		g_Flag_SysRunTimeOut = 1;
	};
	LLOG("#I Sys Heartbeat T[%d]\n",GetNowTick());
}
#endif
//==========

// #ifdef main	// when used Toolchain: tcc and SDL2 is need 
// #undef main
// #endif

int main (int argc,char *argv[]){
	
	int ret = 0;

	LLOG("#I PC-Demo Start : hello world\n");
	MsTick_Init(GetSysTick);
	
	#ifdef CFG_SYS_MALLOC
	MemHeap_Init(1024*8); // byte
	#endif
	
	StaticBuf_Show();
	
	#ifdef CFG_APP_SORT_TIMER
	SortTimer_Init();
	#endif	

	#ifdef CFG_WIN_CMDLINE_PROC
	Input_CmdPara(argc,argv);
	#endif

	#ifdef CFG_VPORT_VPTCL_MGM
	g_pvPPMgm = vPPMgm_Create(47);
	#endif

	#ifdef CFG_VPORT_SIMU_APP
	SimuPort_MasterSlave_Init();
	#endif
	
	// TestA();
	UT_Case_Pub();
	Mode_UTest();
	
	// exit(0);
	
	#ifdef CFG_APP_SORT_TIMER
	do{
		tSTimer* ptmp;
		ptmp = STimer_CreateAndAdd(0, STIMER_TYP_PERIOD, 1000);
		STimer_BindCBF(ptmp,CoTask_SysRunTimeOut);
		STimer_OnOff(ptmp,1);
		// STimer_Show(ptmp);	
		
		// PTask_Period_OneSec();
	}while(0);

	while(1){
		if(g_Flag_SysRunTimeOut == 1){
			break;
		}
		STimer_Run();
	}
	#endif

	LLOG("#PC-Demo-Exit\n");
	// Sleep(100);
	exit(0);
	return ret;
}


//==========
#if 0 // DFT
#include <math.h>


int CC_DFT(double* inx,double* iny, double* a,double* b,int N,int sign){
	
	int ret=RET_OK;
	int i,k;
	double Q;
	double d,c,s;
	double w;
	
	Q= (2*M_PI)/N;
	
	for(k=0;k<N;k++){
		w=k*Q; // 频率w的分量
		a[k]=0.0;
		b[k]=0.0;
		
		for(i=0;i<N;i++){ // n
			d=i*w;
			c=cos(d);
			s=sin(d)*sign;  // 傅里叶变换 与反变换 sin 的符号相反;!!
			a[k]+= c*x[i]+s*y[i];
			b[k]+= c*y[i]-s*x[i];
		}
	}
	
	//
	if(sign == -1){ // 傅里叶反变换 需要 多乘一个 1/N 
		c= 1.0/N;
		for(k=0;k<N;k++){
			a[k]=c*a[k];
			b[k]=c*b[k];
		}
	}
	return ret;
}


#endif













